package com.phison.fenestrapro.dashboard.data;

import java.io.Serializable;

import com.phison.fenestrapro.dashboard.util.DatabaseHelper;
import com.phison.fenestrapro.dashboard.util.GlobalConstants;
import com.vaadin.data.Item;

/**
 *
 * 
 * @author Niall O'Hara
 *
 */
public class ProjectBean implements Serializable, GlobalConstants {

	private static final long serialVersionUID = 1L;
	
	// Start variables that need to be persisted to save project //
	private int project_id;
	private int building_id;
	private int[] facadeIdArray = new int[maxFacades];
	private int[] floorIdArray = new int[maxStoreys];
	
	// Project information
	private String projName;
	private String projDescription;
	private String projNumber;
	private String facadeType; 
	private String buildingType;
	private String locationSetting;
	
	// Site Location
	private double latitude = 0d;
	private double longitude = 0d;
	
	//Building Geometry
	private double length = 0d;
	private double width = 0d;
	private int storeys = 0;
	private double overallBuildingHeight = 0d;
	private double floorToFloor = 0d;
	private double floorToCeiling = 0d;
	
	//Site Orientation
	private String orientation;
	
	// Performance Dashboard - Overall Performance Requirement
	private Double facadePerformance;
	
	// Performance Dashboard - Thermal Performance Values
	private double uValueRoof = 0d;
	private double uValueGroundFloor = 0d;
	private double uValueWalls = 0d;
	private double uValueGlazing = 0d;
	
	// Performance Dashboard - Overall Percentage Glazing
	private Double percentageGlazing;
	
	// Fa�ade Dashboard
	private double[] facadeGlazedPercentage = new double[maxFacades];
	private boolean[] facadeGlazedAreaLock = new boolean[maxFacades];
	private String[] facadeGlazingType = new String[maxFacades];
	private String[] facadeGlazingSpec = new String[maxFacades];
	private double[] facadePercentageFrame = new double[maxFacades];
	private String[] facadeWindowShadingType = new String[maxFacades];
	private String[] facadeWindowConfig = new String[maxFacades];
	private double[] facadeWindowShadingDepth = new double[maxFacades];
	private String[] facadeShadingAngle = new String[maxFacades];
	private String[] facadeLouvreColour = new String[maxFacades];
	private String[] facadeSlatAngle = new String[maxFacades];
	
	// Daylight Dashboard - Daylighting Information
	private double wallThickness = 0d;
	private String averageReflectanceOfInteriorSurfacesText;

	private double[] surroundingFeaturesAverageHeight = new double[maxFacades];
	private double[] surroundingFeaturesAverageDistance = new double[maxFacades];
	
	private double[][][] facadeWindowHeadCillRevealArray = new double[maxFacades][maxStoreys][3];
	
	// End variables that need to be persisted to save project //
	
	private DatabaseHelper database;
	
	public ProjectBean(int project_id, DatabaseHelper database) {

		this.database = database;
		this.project_id = project_id;
		
		Item projectValues = database.getProjectValues(project_id);
		
		// project table - project manager tab
		this.projName = (String) projectValues.getItemProperty("name").getValue();
		this.projDescription = (String) projectValues.getItemProperty("description").getValue();
		this.projNumber = (String) projectValues.getItemProperty("reference_number").getValue();
		this.longitude = (Double) projectValues.getItemProperty("longitude").getValue();
		this.latitude = (Double) projectValues.getItemProperty("latitude").getValue();
		this.locationSetting = (String) projectValues.getItemProperty("location_setting").getValue();
		
		// get the building associated with the project from the project_has_building table
		this.building_id = (Integer) database.getProjectBuildingValue(project_id, "building_id");
		
		Item buildingValues = database.getBuildingValues(this.building_id);
		
		// building table - project manager tab
		this.facadeType = (String) buildingValues.getItemProperty("facade_type").getValue();
		this.buildingType = (String) buildingValues.getItemProperty("building_type").getValue();
		
		// building table - building manager tab
		this.length = (Double) buildingValues.getItemProperty("length").getValue();
		this.width = (Double) buildingValues.getItemProperty("width").getValue();
		this.storeys = (Integer) buildingValues.getItemProperty("storeys").getValue();
		this.floorToFloor = (Double) buildingValues.getItemProperty("floor_to_floor").getValue();
		this.overallBuildingHeight = (Double) buildingValues.getItemProperty("overall_building_height").getValue();
		this.floorToCeiling = (Double) buildingValues.getItemProperty("floor_to_ceiling").getValue();
		this.orientation = (String) buildingValues.getItemProperty("orientation").getValue();
		
		// building table - Performance manager tab
		this.facadePerformance = (Double) buildingValues.getItemProperty("facade_performance").getValue();
		this.uValueRoof = (Double) buildingValues.getItemProperty("u_value_roof").getValue();
		this.uValueWalls = (Double) buildingValues.getItemProperty("u_value_walls").getValue();
		this.uValueGroundFloor = (Double) buildingValues.getItemProperty("u_value_ground_floor").getValue();
		this.uValueGlazing = (Double) buildingValues.getItemProperty("u_value_glazing").getValue();
		this.percentageGlazing = (Double) buildingValues.getItemProperty("overall_percent_glazing").getValue();
		
		// building table - Performance manager tab
		this.wallThickness = (Double) buildingValues.getItemProperty("wall_thickness").getValue();
		this.averageReflectanceOfInteriorSurfacesText = (String) buildingValues.getItemProperty("reflectance_interior_surfaces").getValue();
		
		// get the floors associated with the building from the building_has_floor table
		for (int i = 0; i < maxStoreys; i++){
			this.floorIdArray[i] = (Integer) database.getBuildingFloorID(building_id, i);
		}
		
		Item facadeValues = null;
		Item windowValues = null;
		
		// get the facades associated with the building from the building_has_facade table
		for (int i = 0; i < maxFacades; i++) {
			this.facadeIdArray[i] = (Integer) database.getBuildingFacadeID(building_id, i);
			
			facadeValues = database.getFacadeValues(this.facadeIdArray[i]);
			
			this.facadeGlazedPercentage[i] = (Double) facadeValues.getItemProperty("glazed_percentage").getValue();
			this.facadeGlazedAreaLock[i] = (Boolean) facadeValues.getItemProperty("glazed_area_lock").getValue();
			this.facadeGlazingType[i] = (String) facadeValues.getItemProperty("glazing_type").getValue();
			this.facadeGlazingSpec[i] = (String) facadeValues.getItemProperty("glazing_spec").getValue();
			this.facadePercentageFrame[i] = (Double) facadeValues.getItemProperty("percentage_frame").getValue();
			this.facadeWindowShadingType[i]= (String) facadeValues.getItemProperty("window_shading_type").getValue();
			this.facadeWindowConfig[i] = (String) facadeValues.getItemProperty("window_config").getValue();
			this.facadeWindowShadingDepth[i] = (Double) facadeValues.getItemProperty("window_shading_depth").getValue();
			this.facadeShadingAngle[i] = (String) facadeValues.getItemProperty("shading_angle").getValue();
			this.facadeLouvreColour[i] = (String) facadeValues.getItemProperty("louvre_colour").getValue();
			this.facadeSlatAngle[i] = (String) facadeValues.getItemProperty("slat_angle").getValue();
			
			this.surroundingFeaturesAverageHeight[i] = (Double) facadeValues.getItemProperty("surroundings_avg_height").getValue();
			this.surroundingFeaturesAverageDistance[i] = (Double) facadeValues.getItemProperty("surroundings_avg_distance").getValue();
			
			for (int j = 0; j < maxStoreys; j++) {
				windowValues = database.getWindowValues(this.facadeIdArray[i], this.floorIdArray[j]);
				
				facadeWindowHeadCillRevealArray[i][j][0] = (Double) windowValues.getItemProperty("head_height").getValue();
				facadeWindowHeadCillRevealArray[i][j][1] = (Double) windowValues.getItemProperty("cill_height").getValue();
				facadeWindowHeadCillRevealArray[i][j][2] = (Double) windowValues.getItemProperty("reveal").getValue();
			}
		}
		
		projectValues = null;
		buildingValues = null;
		facadeValues = null;
		windowValues = null;
	}

	/**
	 * @return the project_id
	 */
	public int getProject_id() {
		return project_id;
	}

	/**
	 * @param project_id the project_id to set
	 */
	public void setProject_id(int project_id) {
		this.project_id = project_id;
	}

	/**
	 * @return the building_id
	 */
	public int getBuilding_id() {
		return building_id;
	}

	/**
	 * @param building_id the building_id to set
	 */
	public void setBuilding_id(int building_id) {
		this.building_id = building_id;
	}

	/**
	 * @return the projName
	 */
	public String getProjName() {
		return projName;
	}

	/**
	 * @param projName the projName to set
	 */
	public void setProjName(String projName) {
		this.projName = projName;
		this.database.setProjectValue(project_id, "name", projName);
	}

	/**
	 * @return the projDescription
	 */
	public String getProjDescription() {
		return projDescription;
	}

	/**
	 * @param projDescription the projDescription to set
	 */
	public void setProjDescription(String projDescription) {
		this.projDescription = projDescription;
		this.database.setProjectValue(project_id, "description", projDescription);
	}

	/**
	 * @return the projNumber
	 */
	public String getProjNumber() {
		return projNumber;
	}

	/**
	 * @param projNumber the projNumber to set
	 */
	public void setProjNumber(String projNumber) {
		this.projNumber = projNumber;
		this.database.setProjectValue(project_id, "reference_number", projNumber);
	}

	/**
	 * @return the facadeType
	 */
	public String getFacadeType() {
		return facadeType;
	}

	/**
	 * @param facadeType the facadeType to set
	 */
	public void setFacadeType(String facadeType) {
		this.facadeType = facadeType;
		this.database.setBuildingValue(building_id, "facade_type", facadeType);
	}

	/**
	 * @return the buildingType
	 */
	public String getBuildingType() {
		return buildingType;
	}

	/**
	 * @param buildingType the buildingType to set
	 */
	public void setBuildingType(String buildingType) {
		this.buildingType = buildingType;
		this.database.setBuildingValue(building_id, "building_type", buildingType);
	}

	/**
	 * @return the locationSetting
	 */
	public String getLocationSetting() {
		return locationSetting;
	}

	/**
	 * @param locationSetting the locationSetting to set
	 */
	public void setLocationSetting(String locationSetting) {
		this.locationSetting = locationSetting;
		this.database.setProjectValue(project_id, "location_setting", locationSetting);
	}

	/**
	 * @return the latitude
	 */
	public double getLatitude() {
		return latitude;
	}

	/**
	 * @param latitude the latitude to set
	 */
	public void setLatitude(double latitude) {
		this.latitude = latitude;
		this.database.setProjectValue(project_id, "latitude", latitude);
	}

	/**
	 * @return the longitude
	 */
	public double getLongitude() {
		return longitude;
	}

	/**
	 * @param longitude the longitude to set
	 */
	public void setLongitude(double longitude) {
		this.longitude = longitude;
		this.database.setProjectValue(project_id, "longitude", longitude);
	}

	/**
	 * @return the length
	 */
	public double getLength() {
		return length;
	}

	/**
	 * @param length the length to set
	 */
	public void setLength(double length) {
		this.length = length;
		this.database.setBuildingValue(building_id, "length", length);
	}

	/**
	 * @return the width
	 */
	public double getWidth() {
		return width;
	}

	/**
	 * @param width the width to set
	 */
	public void setWidth(double width) {
		this.width = width;
		this.database.setBuildingValue(building_id, "width", width);
	}

	/**
	 * @return the storeys
	 */
	public int getStoreys() {
		return storeys;
	}

	/**
	 * @param storeys the storeys to set
	 */
	public void setStoreys(int storeys) {
		this.storeys = storeys;
		this.database.setBuildingValue(building_id, "storeys", storeys);
	}

	/**
	 * @return the overallBuildingHeight
	 */
	public double getOverallBuildingHeight() {
		return overallBuildingHeight;
	}

	/**
	 * @param overallBuildingHeight the overallBuildingHeight to set
	 */
	public void setOverallBuildingHeight(double overallBuildingHeight) {
		this.overallBuildingHeight = overallBuildingHeight;
		this.database.setBuildingValue(building_id, "overall_building_height", overallBuildingHeight);
	}

	/**
	 * @return the floorToFloor
	 */
	public double getFloorToFloor() {
		return floorToFloor;
	}

	/**
	 * @param floorToFloor the floorToFloor to set
	 */
	public void setFloorToFloor(double floorToFloor) {
		this.floorToFloor = floorToFloor;
		this.database.setBuildingValue(building_id, "floor_to_floor", floorToFloor);
	}

	/**
	 * @return the floorToCeiling
	 */
	public double getFloorToCeiling() {
		return floorToCeiling;
	}

	/**
	 * @param floorToCeiling the floorToCeiling to set
	 */
	public void setFloorToCeiling(double floorToCeiling) {
		this.floorToCeiling = floorToCeiling;
		this.database.setBuildingValue(building_id, "floor_to_ceiling", floorToCeiling);
	}

	/**
	 * @return the orientation
	 */
	public String getOrientation() {
		return orientation;
	}

	/**
	 * @param orientation the orientation to set
	 */
	public void setOrientation(String orientation) {
		this.orientation = orientation;
		this.database.setBuildingValue(building_id, "orientation", orientation);
	}

	/**
	 * @return the facadePerformance
	 */
	public Double getFacadePerformance() {
		return facadePerformance;
	}

	/**
	 * @param facadePerformance the facadePerformance to set
	 */
	public void setFacadePerformance(double facadePerformance) {
		this.facadePerformance = facadePerformance;
		this.database.setBuildingValue(building_id, "facade_performance", facadePerformance);
	}

	/**
	 * @return the uValueRoof
	 */
	public double getuValueRoof() {
		return uValueRoof;
	}

	/**
	 * @param uValueRoof the uValueRoof to set
	 */
	public void setuValueRoof(double uValueRoof) {
		this.uValueRoof = uValueRoof;
		this.database.setBuildingValue(building_id, "u_value_roof", uValueRoof);
	}

	/**
	 * @return the uValueGroundFloor
	 */
	public double getuValueGroundFloor() {
		return uValueGroundFloor;
	}

	/**
	 * @param uValueGroundFloor the uValueGroundFloor to set
	 */
	public void setuValueGroundFloor(double uValueGroundFloor) {
		this.uValueGroundFloor = uValueGroundFloor;
		this.database.setBuildingValue(building_id, "u_value_ground_floor", uValueGroundFloor);
	}

	/**
	 * @return the uValueWalls
	 */
	public double getuValueWalls() {
		return uValueWalls;
	}

	/**
	 * @param uValueWalls the uValueWalls to set
	 */
	public void setuValueWalls(double uValueWalls) {
		this.uValueWalls = uValueWalls;
		this.database.setBuildingValue(building_id, "u_value_walls", uValueWalls);
	}

	/**
	 * @return the uValueGlazing
	 */
	public double getuValueGlazing() {
		return uValueGlazing;
	}

	/**
	 * @param uValueGlazing the uValueGlazing to set
	 */
	public void setuValueGlazing(double uValueGlazing) {
		this.uValueGlazing = uValueGlazing;
		this.database.setBuildingValue(building_id, "u_value_glazing", uValueGlazing);
	}

	/**
	 * @return the percentageGlazing
	 */
	public Double getPercentageGlazing() {
		return percentageGlazing;
	}

	/**
	 * @param percentageGlazing the maxPercentageGlazing to set
	 */
	public void setPercentageGlazing(double percentageGlazing) {
		this.percentageGlazing = percentageGlazing;
		this.database.setBuildingValue(building_id, "overall_percent_glazing", percentageGlazing);
	}

	/**
	 * @return the wallThickness
	 */
	public double getWallThickness() {
		return wallThickness;
	}

	/**
	 * @param wallThickness the wallThickness to set
	 */
	public void setWallThickness(double wallThickness) {
		this.wallThickness = wallThickness;
		this.database.setBuildingValue(building_id, "wall_thickness", wallThickness);
	}

	/**
	 * @return the averageReflectanceOfInteriorSurfacesText
	 */
	public String getAverageReflectanceOfInteriorSurfacesText() {
		return averageReflectanceOfInteriorSurfacesText;
	}

	/**
	 * @param averageReflectanceOfInteriorSurfacesText the averageReflectanceOfInteriorSurfacesText to set
	 */
	public void setAverageReflectanceOfInteriorSurfacesText(
			String averageReflectanceOfInteriorSurfacesText) {
		this.averageReflectanceOfInteriorSurfacesText = averageReflectanceOfInteriorSurfacesText;
		this.database.setBuildingValue(building_id, "reflectance_interior_surfaces", averageReflectanceOfInteriorSurfacesText);
	}

	/**
	 * @return the facadeWindowHeadCillRevealArray
	 */
	public double[][][] getFacadeWindowHeadCillRevealArray() {
		return facadeWindowHeadCillRevealArray;
	}

	/**
	 * @param facade_id the facade_id to set
	 * @param floor_id the floor_id to set
	 * @param field_id the field_id to set
	 * @param value the value to set
	 */
	public void setFacadeWindowHeadCillRevealArray(int facade_id, int floor_id, int field_id, double value) {
		this.facadeWindowHeadCillRevealArray[facade_id][floor_id][field_id] = value;
		String field = "";
		switch (field_id) {
			case 0:
				field = "head_height";
				break;
			case 1:
				field = "cill_height";
				break;
			case 2:
				field = "reveal";
				break;
		}
		this.database.setWindowValue(facadeIdArray[facade_id], floorIdArray[floor_id], field, value);
	}

	public double getFacadeGlazedPercentage(int facade_num) {
		return facadeGlazedPercentage[facade_num];
	}

	public void setFacadeGlazedPercentage(int facade_num, double facadeGlazedPercentage) {
		this.facadeGlazedPercentage[facade_num] = facadeGlazedPercentage;
		this.database.setFacadeValue(facadeIdArray[facade_num], "glazed_percentage", facadeGlazedPercentage);
	}

	public boolean getFacadeGlazedAreaLock(int facade_num) {
		return facadeGlazedAreaLock[facade_num];
	}

	public void setFacadeGlazedAreaLock(int facade_num, boolean facadeGlazedAreaLock) {
		this.facadeGlazedAreaLock[facade_num] = facadeGlazedAreaLock;
		this.database.setFacadeValue(facadeIdArray[facade_num], "glazed_area_lock", facadeGlazedAreaLock);
	}

	public String getFacadeGlazingType(int facade_num) {
		return facadeGlazingType[facade_num];
	}

	public void setFacadeGlazingType(int facade_num, String facadeGlazingType) {
		this.facadeGlazingType[facade_num] = facadeGlazingType;
		this.database.setFacadeValue(facadeIdArray[facade_num], "glazing_type", facadeGlazingType);
	}

	public String getFacadeGlazingSpec(int facade_num) {
		return facadeGlazingSpec[facade_num];
	}

	public void setFacadeGlazingSpec(int facade_num, String facadeGlazingSpec) {
		this.facadeGlazingSpec[facade_num] = facadeGlazingSpec;
		this.database.setFacadeValue(facadeIdArray[facade_num], "glazing_spec", facadeGlazingSpec);
	}

	public double getFacadePercentageFrame(int facade_num) {
		return facadePercentageFrame[facade_num];
	}

	public void setFacadePercentageFrame(int facade_num, double facadePercentageFrame) {
		this.facadePercentageFrame[facade_num] = facadePercentageFrame;
		this.database.setFacadeValue(facadeIdArray[facade_num], "percentage_frame", facadePercentageFrame);
	}

	public String getFacadeWindowShadingType(int facade_num) {
		return facadeWindowShadingType[facade_num];
	}

	public void setFacadeWindowShadingType(int facade_num, String facadeWindowShadingType) {
		this.facadeWindowShadingType[facade_num] = facadeWindowShadingType;
		this.database.setFacadeValue(facadeIdArray[facade_num], "window_shading_type", facadeWindowShadingType);
	}

	public String getFacadeWindowConfig(int facade_num) {
		return facadeWindowConfig[facade_num];
	}

	public void setFacadeWindowConfig(int facade_num, String facadeWindowConfig) {
		this.facadeWindowConfig[facade_num] = facadeWindowConfig;
		this.database.setFacadeValue(facadeIdArray[facade_num], "window_config", facadeWindowConfig);
	}

	public double getFacadeWindowShadingDepth(int facade_num) {
		return facadeWindowShadingDepth[facade_num];
	}

	public void setFacadeWindowShadingDepth(int facade_num, double facadeWindowShadingDepth) {
		this.facadeWindowShadingDepth[facade_num] = facadeWindowShadingDepth;
		this.database.setFacadeValue(facadeIdArray[facade_num], "window_shading_depth", facadeWindowShadingDepth);
	}

	public String getFacadeShadingAngle(int facade_num) {
		return facadeShadingAngle[facade_num];
	}

	public void setFacadeShadingAngle(int facade_num, String facadeShadingAngle) {
		this.facadeShadingAngle[facade_num] = facadeShadingAngle;
		this.database.setFacadeValue(facadeIdArray[facade_num], "shading_angle", facadeShadingAngle);
	}

	public String getFacadeLouvreColour(int facade_num) {
		return facadeLouvreColour[facade_num];
	}

	public void setFacadeLouvreColour(int facade_num, String facadeLouvreColour) {
		this.facadeLouvreColour[facade_num] = facadeLouvreColour;
		this.database.setFacadeValue(facadeIdArray[facade_num], "louvre_colour", facadeLouvreColour);
	}

	public String getFacadeSlatAngle(int facade_num) {
		return facadeSlatAngle[facade_num];
	}

	public void setFacadeSlatAngle(int facade_num, String facadeSlatAngle) {
		this.facadeSlatAngle[facade_num] = facadeSlatAngle;
		this.database.setFacadeValue(facadeIdArray[facade_num], "slat_angle", facadeSlatAngle);
	}

	public double getSurroundingFeaturesAverageHeight(int facade_num) {
		return surroundingFeaturesAverageHeight[facade_num];
	}

	public void setSurroundingFeaturesAverageHeight(int facade_num, 
			double surroundingFeaturesAverageHeight) {
		this.surroundingFeaturesAverageHeight[facade_num] = surroundingFeaturesAverageHeight;
		this.database.setFacadeValue(facadeIdArray[facade_num], "surroundings_avg_height", surroundingFeaturesAverageHeight);
	}

	public double getSurroundingFeaturesAverageDistance(int facade_num) {
		return surroundingFeaturesAverageDistance[facade_num];
	}

	public void setSurroundingFeaturesAverageDistance(int facade_num, 
			double surroundingFeaturesAverageDistance) {
		this.surroundingFeaturesAverageDistance[facade_num] = surroundingFeaturesAverageDistance;
		this.database.setFacadeValue(facadeIdArray[facade_num], "surroundings_avg_distance", surroundingFeaturesAverageDistance);
	}

}
